#include "FWindows.h"
#include "Framework.h"
#include "GuiEvent.h"
#include "UsefullApi.h"

VMINT last_cur_win_hwnd = -1;
VMINT is_windows_init_done = FALSE;

void WindowsDrawManager(void)
{
	VMINT hwnd = GetActiveWindowHwnd();

	if(is_windows_init_done == FALSE)
	{
		is_windows_init_done = TRUE;
		return;
	}
	
	if(hwnd == -1)
	{
		return;
	}

	if(last_cur_win_hwnd == hwnd)
	{
		RefreshWindow(hwnd);
	}
	else
	{
		ShowWindow(hwnd);
	}
	
	last_cur_win_hwnd = hwnd;
	
}

VMINT GetActiveWindowID(void)
{
	if(win_list == NULL)
	{
		return -1;
	}
	else
	{
		struct common_window_property *p = (struct common_window_property*)win_list->hwnd;
		return p->win_id;
	}
}

VMINT GetActiveWindowHwnd(void)
{
	if(win_list == NULL)
	{
		return -1;
	}
	else
	{
		return win_list->hwnd;
	}
}


void CreateWindowInList(VMINT hwnd)
{
	struct list_windows* p = NULL;
	
	if(win_list == NULL)
	{
		win_list = (struct list_windows*)vm_malloc(sizeof(struct list_windows));
		memset(win_list, 0, sizeof(struct list_windows));
		win_list->hwnd = hwnd;
		win_list->next = NULL;
		return;
	}

	p = (struct list_windows*)vm_malloc(sizeof(struct list_windows));
	memset(p, 0, sizeof(struct list_windows));
	p->hwnd = hwnd;
	p->next = win_list;
	win_list = p;
}

void FreeWindowList(void)
{
	while(win_list)
	{
		struct list_windows* pNext = win_list->next;
		vm_free(win_list);
		win_list = pNext;
	}
	win_list = NULL;
}

void DelWindowFromList(VMINT hwnd)
{
	struct list_windows* cur = NULL;
	struct list_windows* p = win_list;

	if(p->hwnd == hwnd)
	{
		struct list_windows* t = p->next;
		vm_free(p);
		win_list = t;
		return;
	}

	cur = p;
	p = p->next;
	
	while(p)
	{
		if(p->hwnd == hwnd)
		{
			struct list_windows* t = p->next;
			vm_free(p);
			cur->next = t;
			break;
		}
		cur = cur->next;
		p = p->next;
	}
}

void SetWindowTopInList(VMINT hwnd)
{
	DelWindowFromList(hwnd);
	CreateWindowInList(hwnd);
}

void PostWinMessage(VMINT hwnd, VMINT msg_id, VMINT wparam, VMINT lparam)
{
	struct common_window_property *p = (struct common_window_property*)hwnd;
	if(p)
	{
		p->win_msg_proc(hwnd, msg_id, wparam, lparam);
	}
}

void WindowMessageProc(VMINT hwnd, VMINT msg_id, VMINT wparam, VMINT lparam)
{
	struct common_window_property *p = (struct common_window_property*)hwnd;
	switch(msg_id)
	{
	case MSG_WIN_INIT:
		if(p->win_init)
		{
			p->win_init();
		}
		break;
	case MSG_WIN_SHOW:
		if(p->win_show)
		{
			p->win_show();
		}
		UpdateScreen();
		break;
	case MSG_WIN_REFRESH:
		if(p->win_refresh)
		{
			p->win_refresh();
		}
		UpdateScreen();
		break;
	case MSG_WIN_FREE:
		if(p->win_free)
		{
			p->win_free();
		}
		break;
	}
}

VMINT CreateWindow(
	VMINT x, 
	VMINT y, 
	VMINT width, 
	VMINT height, 
	VMINT win_id, 
	VMINT win_type,
	VMSTR win_name, 
	FuncPtr win_init,
 	FuncPtr win_show,
 	FuncPtr win_refresh,
 	FuncPtr win_free,
	void (*touch_event)(VMINT t_event, VMINT xt, VMINT yt),
	void (*win_msg_proc)(VMINT hwnd, VMINT msg_id, VMINT wparam, VMINT lparam)
)
{
	struct common_window_property *p = (struct common_window_property *)vm_malloc(sizeof(struct common_window_property));

	if(p == NULL)
	{
		return 0;
	}

	p->p.x = x;
	p->p.y = y;
	p->p.width = width;
	p->p.height = height;
	p->hwnd = (VMINT)p;
	p->win_id = win_id;
	p->win_type = win_type;
	strcat(p->win_name, win_name);

	p->win_init = win_init;
	p->win_show = win_show;
	p->win_refresh = win_refresh;
	p->win_free = win_free;
	
	p->touch_event = touch_event;
	
	RegisterTouchCustomEventHandle(p->touch_event);
	
	if(win_msg_proc)
	{
		p->is_proc_self = TRUE;
		p->win_msg_proc = win_msg_proc;
	}
	else
	{
		p->is_proc_self = FALSE;
		p->win_msg_proc = WindowMessageProc;
	}

	PostWinMessage(p->hwnd, MSG_WIN_INIT, 0, 0);
	CreateWindowInList(p->hwnd);
	return p->hwnd;
}

void FreeWindow(VMINT hwnd)
{
	struct common_window_property *p = (struct common_window_property*)hwnd;
	if(p)
	{
		RegisterTouchCustomEventHandle(TouchEventDummy);
		PostWinMessage(hwnd, MSG_WIN_FREE, 0, 0);
		DelWindowFromList(hwnd);
		vm_free(p);
		p = NULL;
	}
}

void ShowWindow(VMINT hwnd)
{
	PostWinMessage(hwnd, MSG_WIN_SHOW, 0, 0);
}

void RefreshWindow(VMINT hwnd)
{
	PostWinMessage(hwnd, MSG_WIN_REFRESH, 0, 0);
}

void ShowTopWindow(void)
{
	VMINT hwnd = GetActiveWindowHwnd();
	
	if(hwnd == -1)
	{
		return;
	}
	ShowWindow(hwnd);
}

void CloseWindow(VMINT hwnd)
{
	FreeWindow(hwnd);
	ShowTopWindow();
}

